package com.liust.myproject_client.Service;

import com.liust.myproject.Pojo.PayPojo;
import com.rabbitmq.client.Channel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.*;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.messaging.handler.annotation.Headers;
import org.springframework.messaging.handler.annotation.Payload;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.Map;

/**
 * @author liuyulong
 * @create 2022-03-17 11:00
 * @create 2022-三月  星期四
 * @project MyProject_Client
 */
@Service
public class RabbitMqService {


    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Resource
    private payService payService;

    //    消费者获得消息
    @RabbitListener(
            bindings = @QueueBinding(
                    value = @Queue(value = "pay-queue", durable = "true"),
                    exchange = @Exchange(value = "pay-exchange", durable = "true", type = "topic"),
                    key = "my.pay"
            )
    )
    @RabbitHandler //设置该方法接收消息，这个方法运行后处于等待的状态，有新的消息进来就会自动触发下面的方法处理消息
    public void handleMessage(
            @Payload Map map,
            Channel channel,
            @Headers Map<String, Object> headers,
            Message message
    ) {

        PayPojo receiverPayPojo = (PayPojo) map.get("payPojo");
        String PayOfTransferId = (String) map.get("sendPayId");

        /*
         * payload 有效载荷
         * */
        Long aLong = (Long) headers.get(AmqpHeaders.DELIVERY_TAG);


        logger.info("=====================================");
        logger.info("接收到:" + receiverPayPojo.toString());
        logger.info("接收到:" + PayOfTransferId);
//        所有消息处理后必须进行消息的ack  channel.basicAck()
        logger.info("TagL:" + aLong);

        try {
            if (aLong!=null) {
                logger.info("调用数据库");
                payService.toUpdateTransfer(PayOfTransferId,receiverPayPojo);
                logger.info("调用数据库成功");
            }
//            ack
            channel.basicAck(aLong, false);
        } catch (Exception e) {
            try {
//              nack  当发生异常就返回到通道
                logger.error("nack:发生异常:编号"+aLong+" 异常:"+e.getMessage());
                channel.basicNack(aLong, false, true);
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
        logger.info("=====================================");



    }

}
